package com.xneure.database.sql.handler;

import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import com.xneure.database.DynamicDataSource;
import com.xneure.database.annotation.AutoUpdate;
import com.xneure.database.annotation.DBField;
import com.xneure.database.metaobject.FieldMetaObject;
import com.xneure.database.metaobject.TableMetaObject;
import com.xneure.database.sql.SqlMapping;
import com.xneure.database.sql.ValueConvert;
import com.xneure.utils.ObjectUtil;

public class InsertHandler extends SqlHandler{
	private StringBuilder sql = new StringBuilder("INSERT INTO ");
	private StringBuilder values = new StringBuilder(" VALUES(");
	private StringBuilder where = new StringBuilder(" WHERE ");
	private List<OutreachProvider> outreachHandlers;

	public InsertHandler(){
		setSqlAspect(new SqlAspect(){
		});
	}

	public void resetParam(){
		sql.setLength(12);
		values.setLength(8);
	}

	@Override
	public void addParam(String name,Object value){
		sql.append(name);
		values.append(value);
	}

	@Override
	public String getSql(){
		String concat = sql.toString().concat(values.toString());
		if(outreachHandlers != null){
			StringBuilder sBuilder = new StringBuilder(concat);
			sBuilder.append(";\r\n");
			for(OutreachProvider oh:outreachHandlers){
				sBuilder.append(oh.buildSql());
			}
			concat = DynamicDataSource.getSqlDialect().batchSql(sBuilder.toString());
		}
		return concat;
	}

	@Override
	public void addWhere(String where){
		this.where.append(where);//暂未响应
	}

	@Override
	public boolean isSupport(HandlerType hType,Class<?> cls){
		return HandlerType.INSERT == hType;
	}

	@Override
	public void build(Object obj){
		if(outreachHandlers != null){
			outreachHandlers.clear();
		}
		TableMetaObject metaObject = getMetaObject(obj.getClass());
		String tableName = metaObject.getTableName();
		sql.append(tableName);
		sql.append(" (");
		Set<Entry<String,FieldMetaObject>> entrySet = metaObject.getFields().entrySet();
		for(Entry<String,FieldMetaObject> e:entrySet){
			FieldMetaObject val = e.getValue();
			if(val.isIgnore()){
				if(val.checkOutreachAction(HandlerType.INSERT) == false || null == val.getAnnotation() || val.getAnnotation().relation().length() < 1){
					continue;
				}
			}
			Object value = val.getValue(obj);
			DBField ann = val.getAnnotation();
			if(value == null){
				if(null != ann && (ann.autoUpdate() == AutoUpdate.CREATE || ann.autoUpdate() == AutoUpdate.CHANGE)){
					ValueConvert valueConvert = getValueConvert();
					value = valueConvert.getRandomValue(val.getType());
					ObjectUtil.modifyFieldValue(obj,val.getField().getName(),value);
					value = val.getValue(obj);
				}else{
					if(null == value && sqlAspect.discardNull(metaObject,val)){
						continue;
					}
				}
			}else{
				if(null != ann && ann.relation().length() > 0){
					if(outreachHandlers == null){
						outreachHandlers = new ArrayList<>();
					}
					outreachHandlers.add(new OutreachProvider(obj,val,SqlMapping.getHandler(HandlerType.INSERT,val.getClass())));
					continue;
				}
			}
			sql.append(e.getKey());
			values.append(sqlAspect.processValue(metaObject,e.getValue(),value));
			sql.append(",");
			values.append(",");
		}
		sql.setLength(sql.length() - 1);
		values.setLength(values.length() - 1);
		sql.append(")");
		values.append(")");
	}

	protected OutreachProvider name(){
		return null;
	}
}
